package org.wcf.util.freeMarker;

import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.wcf.util.FileUtil;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @author wuchaofei
 * @date 2016/3/22
 */
public class MybatisXmlGen {
    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
        resultMapGen("rush_attr","rush_attrs", "out/mybatis", "id,group_id,name,desc");
//        simpleGen("product","D:\\le\\workspace\\php_lemall\\usa_wap\\trunk\\application\\models\\Product.php","out/mybatis");
    }

    public static void resultMapGen(String className,String table, String toFile, String dataStr) throws ParserConfigurationException, SAXException, IOException {
        String[] datas={};
        if(StringUtils.isNotEmpty(dataStr)){
            datas = dataStr.split(",");
        }
        Map<String,Object> map=new HashMap<String,Object>();
        map.put("attrs", Arrays.asList(datas));
        //表名
        map.put("table",table);
        //驼峰表名
        className = FreemarkerUtil.splitJoinUpperFirstWord(className);
        map.put("tableMap",readTableMap(null));
        map.put("className",FreemarkerUtil.toUpperCaseFirstOne(className));
        //文件夹名添加文件名
        toFile = new File(toFile,FreemarkerUtil.toUpperCaseFirstOne(className+".xml")).getAbsolutePath();
        FreemarkerUtil.resultMapGen(className, toFile, map);
    }

    /**
     * 从php-model文件读取sql数据，拼装成mybatis-mapper文件
     * @param className model(名字)
     * @param fromFile php-model文件全路径
     * @param toDir 输出目录
     */
    public static void simpleGen(String className, String fromFile, String toDir){
        Map<String,Object> map=new HashMap<String,Object>();
        map.put("functions", FileUtil.phpFunctions(fromFile));
        className = FreemarkerUtil.splitJoinUpperFirstWord(className);
        map.put("className",className);
        //文件夹名添加文件名
        String toFile = new File(toDir,FreemarkerUtil.toUpperCaseFirstOne(className+".xml")).getAbsolutePath();
        try {
            map.put("tableMap",readTableMap(null));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
        FreemarkerUtil.genSimpleMybatis(className, toFile, map);
    }

    /**
     * 避免读取dtd验证内部类
     */
    static class IgnoreDTDEntityResolver implements EntityResolver {
        @Override
        public InputSource resolveEntity(String arg0, String arg1) throws SAXException, IOException {
            return new InputSource(new ByteArrayInputStream("<?xml version='1.0' encoding='UTF-8'?>".getBytes()));
        }
    }

    /**
     * 将存放到xml文件的表信息，读取到map中供freemarker使用
     * @param path
     * @return
     * @throws IOException
     * @throws SAXException
     * @throws ParserConfigurationException
     */
    public static Map readTableMap(String path) throws IOException, SAXException, ParserConfigurationException {
        if(StringUtils.isEmpty(path)){
            path = "E:/le/MybatisPluginMain/src/main/java/com/mybatis/gen/out/table/TableMap.xml";
        }
        File f =new File(path);
        if (!f.exists()){
            System.err.println(path + " is not exits!!");
            return new HashMap();
        }
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        builder.setEntityResolver(new IgnoreDTDEntityResolver());
        Document document = builder.parse(f);
        NodeList tables = document.getElementsByTagName("table");

        //存放各表
        Map<String,Object> tablesMap = new HashMap<String, Object>();

        for (int i = 0; i < tables.getLength(); i++) {
            Node tableNode = tables.item(i);
            if(tableNode instanceof Element){
                Element  table = (Element)tableNode;
                String tableName = table.getAttribute("name");
                Map<String,Object> tableMap=new HashMap<String,Object>();
                NodeList children = table.getChildNodes();

                for (int j = 0; j < children.getLength(); j++) {
                    Node childNode = children.item(j);
                    if(childNode instanceof Element) {
                        Element child = (Element)childNode;
                        //                <column columnName="id" javaProperty="id" jdbcTypeName="INTEGER" />
                        String columnName = child.getAttribute("columnName");
                        String javaProperty = child.getAttribute("javaProperty");
                        String jdbcTypeName = child.getAttribute("jdbcTypeName");
                        String javaTypeName = child.getAttribute("javaTypeName");
                        Map<String,String> colMap = new HashMap<String,String>();
                        colMap.put("columnName",columnName);
                        colMap.put("javaProperty",javaProperty);
                        colMap.put("jdbcTypeName",jdbcTypeName);
                        colMap.put("javaTypeName",javaTypeName);
                        //存放到以列名为主键的map
                        tableMap.put(columnName,colMap);
                    }
                }
                tablesMap.put(tableName, tableMap);
            }
        }
        System.out.println(tablesMap);
        return tablesMap;
    }
}
